package com.core.managers;

import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.Session;

import com.core.hibernate.HibernateFetchRequest;
import com.core.protocols.IAuthenticationDelegate;
import com.core.protocols.IServiceLayerDelegate;
import com.core.servicelayer.HibernateServiceLayer;
import com.core.utils.GlobalConstants;
import com.entities.user.servicelayer.UserListLayer;
import com.model.UserContextName;
import com.model.user.User;

public class LoginManager implements IAuthenticationDelegate, IServiceLayerDelegate {

	private static LoginManager Instance = null;
	private boolean isValidUser = false;
	private boolean isLoginFormDisplaying = false;
	private int loginAttemptsCount = 0;
	private int loginFormOpenedInstances = 0;
	private boolean isLoginGetMethodExecuted = false;
	private int userId = -1;

	public boolean isLoginGetMethodExecuted() {

		return isLoginGetMethodExecuted;
	}

	public void setLoginGetMethodExecuted(boolean isLoginGetMethodExecuted) {

		this.isLoginGetMethodExecuted = isLoginGetMethodExecuted;
	}

	public boolean hasClosedAllLoginForms() {

		return (loginFormOpenedInstances < 1);
	}

	public void incrementLoginformOpenAttepts() {

		loginFormOpenedInstances++;
	}

	public void decrementLoginformOpenAttepts() {

		loginFormOpenedInstances--;
	}

	public void resetLoginformOpenAttepts() {

		loginFormOpenedInstances = 0;
	}

	public int getLoginAttemptsCount() {

		return loginAttemptsCount;
	}

	public void setLoginAttemptsCount(int loginAttemptsCount) {

		this.loginAttemptsCount = loginAttemptsCount;
	}

	public boolean isValidUser() {

		return isValidUser;
	}

	public void setValidUser(boolean isValidUser) {

		this.isValidUser = isValidUser;
		if (!isValidUser) {

		}
	}

	public boolean isLoginFormDisplaying() {

		return isLoginFormDisplaying;
	}

	public void setLoginFormDisplaying(boolean isLoginFormDisplaying) {

		this.isLoginFormDisplaying = isLoginFormDisplaying;
	}

	public int getUserId() {

		return userId;
	}

	public void setUserId(int userId) {

		this.userId = userId;
	}

	public static LoginManager sharedInstance() {

		if (Instance == null) {
			Instance = new LoginManager();
		}
		return Instance;
	}

	public static Boolean authorizedUserForRequest(ServletRequest request) {

		SessionManager sessionManager = SessionManager.sharedInstance();
		String sessionIsAuthorizedString = (String) sessionManager.getAttributeValue(GlobalConstants.SM_ATTRIBUTE_IS_AUTHORIZED);
		boolean isAuthorized = "true".equalsIgnoreCase(sessionIsAuthorizedString);

		return isAuthorized;
	}

	public boolean performUserCheck(String userName, String userPassword) {

		this.isValidUser = false;
		this.userId = -1;

		UserListLayer layer = new UserListLayer();
		layer.setLayerDelegate(this);
		layer.setUserInfo("PasswordValidation");
		layer.checkValidPassword(userName, userPassword);

		return this.isValidUser;
	}

	public Set<String> userContextSet() {
		Set<String> result = null;
		Session session = SessionFactoryManager.sharedInstance().openSession();
		try{
			User user = (User)session.get(User.class, new Integer(this.userId));
			if (user != null){
				List<UserContextName> userContextNameList = user.getUserCategory().getUserRole().getAvailableContexts();
				if (userContextNameList != null){
					result = new HashSet<String>();
					Iterator<UserContextName>iterator = userContextNameList.iterator();
					while (iterator.hasNext()){
						UserContextName contextName = iterator.next();
						result.add(contextName.getName());
					}
				}
			}
		}finally{
			session.close();
		}
		return result;
	}

	@Override
	public boolean isAuthenticated() {

		return true;
	}

	@Override
	public Integer permissions() {

		return 0;
	}

	@Override
	public <T> void responseResponseItemsList(final List<T> items, final Object request, final Exception exception) {

		HibernateServiceLayer layer = (HibernateServiceLayer) request;
		if ("PasswordValidation".equalsIgnoreCase((String) layer.getUserInfo())) {
			this.userId = -1;
			this.isValidUser = false;
			if (items == null) {
				return;
			}
			this.isValidUser = (items.size() == 1);

			if (this.isValidUser) {
				User user = (User) items.get(0);
				this.userId = user.getId();

			} else {

			}
		}
	}

	public void doDefaultRedirection(HttpServletRequest request, HttpServletResponse response) throws IOException {

		if (this.isValidUser) {
			loginAttemptsCount = -1;
			this.isLoginFormDisplaying = false;
			response.sendRedirect(GlobalConstants.SERVLET_DASHBOARD);
		} else {
			this.resetLoginformOpenAttepts();
			loginAttemptsCount++;
			this.isLoginFormDisplaying = true;
			response.sendRedirect(GlobalConstants.SERVLET_LOGIN);
		}

	}
}
